﻿//--------------------------------------------------------------------------------------------------------------------------------
// <copyright file="ThrowHelper.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>Exul</author>
//--------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.FiniteElementMethod
{
    using System;
    using System.Globalization;

    /// <summary>Provides helper methods to throw exceptions.</summary>
    public static class ThrowHelper
    {
        /// <summary>Creates an instance of exception for case when end value is less than start value.</summary>
        /// <param name="startValueArgumentName">The argument name for start value.</param>
        /// <param name="startValue">The start value.</param>
        /// <param name="endValueArgumentName">The argument name for end value.</param>
        /// <param name="endValue">The end value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentException EndValueLessThanStartValue(
            string startValueArgumentName, double startValue, string endValueArgumentName, double endValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.EndValueLessThanStartValue,
                endValueArgumentName,
                startValueArgumentName,
                startValue,
                endValue);
            return new ArgumentException(message, endValueArgumentName);
        }

        /// <summary>Creates an instance of exception for case when step is negative or equal to zero.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException StepIsNegativeOrEqualToZero(string argumentName, double argumentValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.StepIsNegativeOrZero,
                argumentName,
                argumentValue);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }

        /// <summary>Creates an instance of exception for case when exhaustion is negative or equal to zero.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException ExhaustionIsNegativeOrEqualToZero(string argumentName, double argumentValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.ExhaustionIsNegativeOrZero,
                argumentName,
                argumentValue);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }

        /// <summary>Creates an exception for case when count of points is less than it is expected.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <param name="minimalRequiredValue">The minimal required value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException PointsCountIsLessThanRequired(
            string argumentName, int argumentValue, int minimalRequiredValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.PointsCountIsLessThanRequired,
                argumentName,
                argumentValue,
                minimalRequiredValue);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }

        /// <summary>
        ///     Creates an exception for case when the specified grid cannot be considered as axially symmetric grid.
        /// </summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="startValue">The start value on the first axis.</param>
        /// <param name="minimalAcceptableStartValue">The minimal acceptable start value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentException InvalidAxiallySymmetricGrid(
            string argumentName, double startValue, double minimalAcceptableStartValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.InvalidAxiallySymmetricGrid,
                argumentName,
                minimalAcceptableStartValue,
                startValue);
            return new ArgumentException(message, argumentName);
        }

        /// <summary>Creates an exception for case when the one-dimensional grid is invalid.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="errorDescription">The error description.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentException InvalidGrid(string argumentName, string errorDescription)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.InvalidGrid,
                argumentName,
                errorDescription);
            return new ArgumentException(message, argumentName);
        }

        /// <summary>Creates an exception for case when relative magnetic permeability is negative or equal to zero.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException RelativeMagneticPermeabilityIsNegativeOrEqualToZero(
            string argumentName, double argumentValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.RelativeMagneticPermeabilityIsNegativeOrEqualToZero,
                argumentName,
                argumentValue);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }

        /// <summary>Creates an exception for case when electric conductivity is negative or equal to zero.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException ElectricConductivityIsNegativeOrEqualToZero(
            string argumentName, double argumentValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.ElectricConductivityIsNegativeOrEqualToZero,
                argumentName,
                argumentValue);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }

        /// <summary>Creates an exception for case when start border and end border specifies an invalid location.</summary>
        /// <param name="startBorderArgumentName">The argument name for start border parameter.</param>
        /// <param name="startBorderValue">The start border value.</param>
        /// <param name="endBorderArgumentName">The argument name for end border parameter.</param>
        /// <param name="endBorderValue">The end border value.</param>
        /// <param name="minimalAcceptableSize">The minimal acceptable difference between start border and end border.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException InvalidLocation(
            string startBorderArgumentName,
            double startBorderValue,
            string endBorderArgumentName,
            double endBorderValue,
            double minimalAcceptableSize)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.InvalidLocation,
                startBorderArgumentName,
                endBorderArgumentName,
                minimalAcceptableSize,
                startBorderValue,
                endBorderValue);
            return new ArgumentOutOfRangeException(endBorderArgumentName, endBorderValue, message);
        }

        /// <summary>Creates an exception for case when start border and end border specifies an invalid location.</summary>
        /// <param name="startBorderArgumentName">The argument name for start border parameter.</param>
        /// <param name="startBorderIndex">The start border point index.</param>
        /// <param name="endBorderArgumentName">The argument name for end border parameter.</param>
        /// <param name="endBorderIndex">The end border point index.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException InvalidLocationInGrid(
            string startBorderArgumentName,
            int startBorderIndex,
            string endBorderArgumentName,
            int endBorderIndex)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.InvalidLocationInGrid,
                startBorderArgumentName,
                endBorderArgumentName,
                startBorderIndex,
                endBorderIndex);
            return new ArgumentOutOfRangeException(endBorderArgumentName, endBorderIndex, message);
        }

        /// <summary>Creates an exception for case when border of element location is out of grid.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="borderValue">The border value.</param>
        /// <param name="borderInGrid">The border in grid.</param>
        /// <param name="borderName">The border name.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException BorderIsOutOfGrid(
            string argumentName, double borderValue, double borderInGrid, string borderName)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.BorderIsOutOfGrid,
                borderName,
                argumentName,
                borderValue,
                borderInGrid);
            return new ArgumentOutOfRangeException(argumentName + "." + borderName, borderValue, message);
        }

        /// <summary>Creates an exception for case when index of point is negative.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException PointIndexIsNegative(string argumentName, int argumentValue)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.PointIndexIsNegative,
                argumentName,
                argumentValue);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }

        /// <summary>Creates an exception for case when scheme function is not defined at the current state of scheme.</summary>
        /// <param name="functionIndex">The index of function.</param>
        /// <param name="currentLayerIndex">The index of current layer.</param>
        /// <returns>An instance of exception.</returns>
        public static InvalidOperationException SchemeFunctionIsNotDefined(int functionIndex, int currentLayerIndex)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.SchemeFunctionIndexIsNotDefined,
                functionIndex,
                currentLayerIndex);
            return new InvalidOperationException(message);
        }

        /// <summary>Creates an exception for case when function index is out of expected range.</summary>
        /// <param name="argumentName">The argument name.</param>
        /// <param name="argumentValue">The argument value.</param>
        /// <param name="minimalIndex">The minimal acceptable index.</param>
        /// <param name="maximalIndex">The maximal acceptable index.</param>
        /// <returns>An instance of exception.</returns>
        public static ArgumentOutOfRangeException FunctionIndexIsOutOfRange(
            string argumentName, int argumentValue, int minimalIndex, int maximalIndex)
        {
            var message = string.Format(
                CultureInfo.CurrentCulture,
                Properties.Resources.FunctionIndexIsOutOfRange,
                argumentName,
                argumentValue,
                minimalIndex,
                maximalIndex);
            return new ArgumentOutOfRangeException(argumentName, argumentValue, message);
        }
    }
}